package org.jeecg.common.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import org.jeecg.common.util.minio.MinioUtil;
import org.jeecg.common.util.util_entity.ContentTypeEnum;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.errors.MinioException;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import lombok.Cleanup;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import static cn.hutool.core.text.CharSequenceUtil.isBlank;

@Slf4j
public class JlMinioUtils {
    static String minioUrl = "http://127.0.0.1:9001/";

    static String minioName = "minioadmin";

    static String minioPass = "minioadmin";
    /**
     * 获取文件流
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public static InputStream getMinioFile(String bucketName, String objectName) {
        InputStream inputStream = null;
        try {
            initMinio(minioUrl, minioName, minioPass);
            GetObjectArgs objectArgs = GetObjectArgs.builder().object(objectName)
                    .bucket(bucketName).build();
            inputStream = MinioUtil.minioClient.getObject(objectArgs);
        } catch (Exception e) {
            log.info("文件获取失败" + e.getMessage());
        }
        return inputStream;
    }

       public static InputStream getMinioFileByUrl(String url) {
        String objectName = StrUtil.removePrefix(url, minioUrl + MinioUtil.bucketName);
        InputStream minioFile = getMinioFile(MinioUtil.bucketName, objectName);
        return minioFile;
    }

       @SneakyThrows
    public static MultipartFile convertMinioUrlToMultiPart(String minioUrl, String name, String originalFilename, String contentType) {
        InputStream minioFileByUrl = getMinioFileByUrl(minioUrl);
        return new MockMultipartFile(name, originalFilename, contentType, minioFileByUrl);
    }

    /**
     * 根据minioUrl获取zip文件
     * @param urls
     * @param contentTypeTab 入参
     * @return {@link ByteArrayOutputStream }
     * @author zjarlin
     * @since 2023/11/26
     */

    public static ByteArrayOutputStream getZipByUrls(List<String> urls, ContentTypeEnum contentTypeTab) {
        List<MultipartFile> collect = urls.stream().map(e -> {
            InputStream minioFileByUrl = getMinioFileByUrl(e);
            String fileNameByUrl = getFileNameByUrl(e);
            MultipartFile multipartFile = convertMinioUrlToMultiPart(e, fileNameByUrl, fileNameByUrl, contentTypeTab.getApplication());
            String originalFilename = multipartFile.getOriginalFilename();

            return multipartFile;
        }).collect(Collectors.toList());

        ByteArrayOutputStream zipStreamFromMultipartFiles = getZipStreamFromMultipartFiles(collect);
        return zipStreamFromMultipartFiles;
    }

    @SneakyThrows(IOException.class)
    public static ByteArrayOutputStream getZipStreamFromMultipartFiles(List<MultipartFile> multipartFiles) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        @Cleanup ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        for (MultipartFile file : multipartFiles) {
            ZipEntry zipEntry = new ZipEntry(file.getOriginalFilename());
            zipOutputStream.putNextEntry(zipEntry);
            zipOutputStream.write(file.getBytes());
            zipOutputStream.closeEntry();
        }

        return outputStream;
    }

    public static String getFileNameByUrl(String url) {
        if (isBlank(url)) {
            return "";
        }
        String name = FileUtil.getName(url);
        String decode = cn.hutool.core.net.URLDecoder.decode(name, StandardCharsets.UTF_8);
        return decode;
    }


    //url转file
    public static File getFileByUrl(String fileUrl) {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        BufferedOutputStream stream = null;
        InputStream inputStream = null;
        File file = null;
        try {
            URL imageUrl = new URL(fileUrl);
            HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            inputStream = conn.getInputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }
            file = File.createTempFile("file", fileUrl.substring(fileUrl.lastIndexOf("."), fileUrl.length()));
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            stream = new BufferedOutputStream(fileOutputStream);
            stream.write(outStream.toByteArray());
        } catch (Exception e) {
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (stream != null) {
                    stream.close();
                }
                outStream.close();
            } catch (Exception e) {
            }
        }
        return file;
    }









    @SneakyThrows
    public static boolean doesObjectExist(String bucketName, InputStream inputStream) {
        try {
            // Initialize Minio client
            MinioClient minioClient = initMinio(minioUrl, minioName, minioPass);

            // Create a temporary file for the input stream
            File tempFile = File.createTempFile("temp", ".tmp");
            FileOutputStream outputStream = new FileOutputStream(tempFile);
            IoUtil.copy(inputStream, outputStream);
            outputStream.close();

            // Check if object exists by comparing content
            GetObjectArgs object = GetObjectArgs.builder().bucket(bucketName).object(tempFile.getName()).build();

            InputStream objectStream = minioClient.getObject(object);
            IoUtil.contentEquals(objectStream, new FileInputStream(tempFile));
            objectStream.close();

            // Delete the temporary file
            tempFile.delete();

            return true;

        } catch (MinioException | IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private static MinioClient initMinio(String minioUrl, String minioName, String minioPass) {
        return MinioClient.builder().endpoint(minioUrl).credentials(minioName, minioPass).build();
    }

}
